package com.xh.filepicker.sdk.ui;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.xh.filepicker.sdk.R;
import com.xh.filepicker.sdk.XHFilePicker;
import com.xh.filepicker.sdk.adapter.DirectoryAdapter;
import com.xh.filepicker.sdk.adapter.DirectoryStackAdapter;
import com.xh.filepicker.sdk.models.Config;
import com.xh.filepicker.sdk.models.DirectoryModel;
import com.xh.filepicker.sdk.utils.BarUtils;
import com.xh.filepicker.sdk.utils.EtInputFilterUtil;
import com.xh.filepicker.sdk.utils.KeyboardUtils;
import com.xh.filepicker.sdk.utils.SimpleItemDecoration;
import com.xh.filepicker.sdk.widget.ClearEditText;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;


/**
 * 基于1.0.2(2021/1/10)版本修改 https://github.com/abhishekti7/UnicornFilePicker
 * Created by zhuangshaobo on 2021/6/15.
 */
public class FilePickerActivity extends AppCompatActivity {

    private ImageButton mCloseBtn; //关闭
    private ImageButton mSearchBtn; //搜索
    private Button mOkBtn; //确定
    private RelativeLayout mSearchLayout; //搜索Layout
    private ClearEditText mSearchEt; //搜索框
    private TextView mSearchRightTv; //搜索-取消
    private RecyclerView mDirPathRv; //目录条
    private RecyclerView mDirFileRv; //目录文件列表
    private TextView mNoFileTv; //列表空提示

    private File root_dir; //根目录
    private ArrayList<String> selected_files; //选中的文件路径
    private ArrayList<DirectoryModel> arr_dir_stack; //目录条列表数据
    private ArrayList<DirectoryModel> arr_files; //列表数据

    private DirectoryStackAdapter stackAdapter;
    private DirectoryAdapter directoryAdapter;

    private Config config;
    private ArrayList<String> filters; //只显示需要的文件类型

    private static final int PERMISSION_REQUESTCODE = 1;
    private String[] permissions = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        config = Config.getInstance();
        BarUtils.transparentBar(getWindow()); //全屏布局拉到状态栏/导航栏，透明状态栏/导航栏
        BarUtils.setStatusBarLightMode(getWindow(), true);
        if (permission()) {
            init();
        }
    }

    private void init() {
        setContentView(R.layout.fp_activity_file_picker);
        mCloseBtn = findViewById(R.id.btn_close);
        mSearchBtn = findViewById(R.id.btn_search);
        mOkBtn = findViewById(R.id.btn_ok);
        mSearchLayout = findViewById(R.id.rl_search);
        mSearchEt = findViewById(R.id.et_search);
        mSearchRightTv = findViewById(R.id.tv_right);
        mDirPathRv = findViewById(R.id.rv_dir_path);
        mDirFileRv = findViewById(R.id.rv_dir_file);
        mNoFileTv = findViewById(R.id.tv_no_file);

        mCloseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        mSearchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mSearchLayout.setVisibility(View.VISIBLE);
                KeyboardUtils.showSoftInput(mSearchEt);
            }
        });
        mOkBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("FilePickerSDK", "selected pathList toString() " + selected_files.toString());
                Intent intent = new Intent();
                intent.putStringArrayListExtra(XHFilePicker.RESULT_DATA, selected_files);
                setResult(RESULT_OK, intent);
                finish();
            }
        });
        mSearchEt.setFilters(new InputFilter[]{EtInputFilterUtil.setEditTextInputSpace(), EtInputFilterUtil.setEditTextInputSpeChat()});
        mSearchEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                directoryAdapter.getFilter().filter(s);
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        mSearchRightTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mSearchLayout.setVisibility(View.GONE);
                KeyboardUtils.hideSoftInput(mSearchEt);
                mSearchEt.setText("");
            }
        });

        initConfig();
    }

    private void initConfig() {
        filters = config.getExtensionFilters();
        if (!TextUtils.isEmpty(config.getRootDir())) {
            root_dir = new File(config.getRootDir());
        } else {
            root_dir = Environment.getExternalStorageDirectory();
        }
        selected_files = new ArrayList<>();
        arr_dir_stack = new ArrayList<>();
        arr_files = new ArrayList<>();

        setUpDirectoryStackView();
        setUpFilesView();

        fetchDirectory(new DirectoryModel(
                true,
                root_dir.getAbsolutePath(),
                root_dir.getName(),
                root_dir.lastModified(),
                root_dir.listFiles() == null ? 0 : root_dir.listFiles().length
        ));
    }

    private void setUpFilesView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(FilePickerActivity.this);
        mDirFileRv.setLayoutManager(layoutManager);
        directoryAdapter = new DirectoryAdapter(FilePickerActivity.this, arr_files, new DirectoryAdapter.onFilesClickListener() {
            @Override
            public void onClicked(DirectoryModel model) { //目录点击
                if (mSearchLayout.getVisibility() == View.VISIBLE) {
                    mSearchRightTv.performClick();
                }
                fetchDirectory(model);
            }

            @Override
            public void onFileSelected(DirectoryModel fileModel) { //目录文件选中/取消
                if (config.isSelectMultiple()) {
                    if (selected_files.contains(fileModel.getPath())) {
                        selected_files.remove(fileModel.getPath());
                    } else {
                        selected_files.add(fileModel.getPath());
                    }
                    if (config.getSelectMaxNum() > 0 && selected_files.size() > 0) {
                        mOkBtn.setText("确定(" + selected_files.size() + "/" + config.getSelectMaxNum() + ")");
                    }
                } else {
                    selected_files.clear();
                    selected_files.add(fileModel.getPath());
                }
                mOkBtn.setEnabled(selected_files.size() > 0);
            }
        });
        mDirFileRv.setAdapter(directoryAdapter);
        directoryAdapter.notifyDataSetChanged();
        if (config.addItemDivider()) {
            mDirFileRv.addItemDecoration(new SimpleItemDecoration(FilePickerActivity.this));
        }
    }

    private void setUpDirectoryStackView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(FilePickerActivity.this, RecyclerView.HORIZONTAL, false);
        mDirPathRv.setLayoutManager(layoutManager);
        stackAdapter = new DirectoryStackAdapter(FilePickerActivity.this, arr_dir_stack, new DirectoryStackAdapter.onDirectoryStackListener() {
            @Override
            public void onDirClicked(DirectoryModel model) { //目录条点击item
                mSearchRightTv.performClick();
                arr_dir_stack = new ArrayList<>(arr_dir_stack.subList(0, arr_dir_stack.indexOf(model) + 1));
                setUpDirectoryStackView();
                fetchDirectory(arr_dir_stack.remove(arr_dir_stack.size() - 1));
            }
        });
        mDirPathRv.setAdapter(stackAdapter);
        stackAdapter.notifyDataSetChanged();
    }

    /**
     * Fetches list of files in a folder and filters files if filter present
     */
    private void fetchDirectory(DirectoryModel model) {
//        rlProgress.setVisibility(View.VISIBLE);
        arr_files.clear();
        File dir = new File(model.getPath());
        File[] files_list = dir.listFiles();
        if (files_list != null) {
            for (File file : files_list) {
                DirectoryModel directoryModel = new DirectoryModel();
                directoryModel.setDirectory(file.isDirectory());
                directoryModel.setName(file.getName());
                directoryModel.setPath(file.getAbsolutePath());
                directoryModel.setLast_modif_time(file.lastModified());

                if (config.showHidden() || !file.isHidden()) {
                    if (file.isDirectory()) {
                        if (file.listFiles() != null) {
                            int len = Objects.requireNonNull(file.listFiles(new FileFilter() {
                                @Override
                                public boolean accept(File file) {
                                    if (!config.showHidden() && file.isHidden()) { //不显示隐藏文件,不计数
                                        return false;
                                    }
                                    if (!file.isDirectory()) {
                                        if (config.showOnlyDirectory()) { //只显示目录,不计文件
                                            return false;
                                        }
                                        if (filters != null) { //不是过滤的扩展名,不计数
                                            try {
                                                String fileName = file.getName();
                                                String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
                                                return filters.contains(extension.toLowerCase());
                                            } catch (Exception e) {
                                                return false;
                                            }
                                        }
                                    }

                                    return true;
                                }
                            })).length;
                            directoryModel.setNum_files(len);
                        }
                        arr_files.add(directoryModel);
                    } else {
                        if (!config.showOnlyDirectory()) {
                            directoryModel.setSize(file.length());
                            // Filter out files if filters specified
                            if (filters != null) {
                                try {
                                    // Extract the file extension
                                    String fileName = file.getName();
                                    String extension = fileName.substring(fileName.lastIndexOf("."));
                                    for (String filter : filters) {
                                        if (extension.toLowerCase().contains(filter)) {
                                            arr_files.add(directoryModel);
                                        }
                                    }
                                } catch (Exception e) {
//                                Log.e("FilePickerSDK", "Encountered a file without an extension: ", e);
                                }
                            } else {
                                arr_files.add(directoryModel);
                            }
                        }
                    }
                }

            }
            Collections.sort(arr_files, new CustomFileComparator());

            arr_dir_stack.add(model);
            mDirPathRv.scrollToPosition(arr_dir_stack.size() - 1);
        }
        if (arr_files.size() == 0) {
            mNoFileTv.setVisibility(View.VISIBLE);
        } else {
            mNoFileTv.setVisibility(View.GONE);
        }
//        rlProgress.setVisibility(View.GONE);
        stackAdapter.notifyDataSetChanged();
        directoryAdapter.setDataList(arr_files);
    }

    // Custom Comparator to sort the list of files in lexicographical order
    public static class CustomFileComparator implements Comparator<DirectoryModel> {
        @Override
        public int compare(DirectoryModel o1, DirectoryModel o2) {
            if (o1.isDirectory() && o2.isDirectory()) {
                return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
            } else if (o1.isDirectory() && !o2.isDirectory()) {
                return -1;
            } else if (!o1.isDirectory() && o2.isDirectory()) {
                return 1;
            } else {
                return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
            }
        }
    }

    /**
     * 动态授权
     */
    private boolean permission() {
        boolean isPermission = true;
        for (int i = 1; i < permissions.length; i++) {
            if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                isPermission = false;
                break;
            }
        }
        if (!isPermission) {
            //没有授权
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUESTCODE);
        }
        return isPermission;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PERMISSION_REQUESTCODE:
                StringBuilder text = new StringBuilder();
                boolean isPermission = true;
                for (int i = 1; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        isPermission = false;
                        if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {//用户选择了禁止不再询问
                            if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                                text.append("存储/");
                            }
                        }
                    }
                }
                if (isPermission) {
                    BarUtils.transparentBar(getWindow());
                    init();
                } else {
                    if (!TextUtils.isEmpty(text)) {
                        text.deleteCharAt(text.length() - 1);
                        Toast.makeText(this, "请在应用权限打开 " + text + " 权限", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(this, "使用该功能需要存储权限", Toast.LENGTH_LONG).show();
                    }

                    finish();
                }
                break;
            default:
                break;
        }
    }

    @Override
    public void onBackPressed() {
        if (arr_dir_stack.size() > 1) {
            // pop off top value and display
            arr_dir_stack.remove(arr_dir_stack.size() - 1);
            DirectoryModel model = arr_dir_stack.remove(arr_dir_stack.size() - 1);
            fetchDirectory(model);
        } else {
            // Nothing left in stack so exit
            Intent intent = new Intent();
            setResult(config.getReqCode(), intent);
            setResult(RESULT_CANCELED, intent);
            finish();
        }
    }
}